import time
# 这里导包只能到下面这个，而不能到from datetime import datetime,因为下面用到了timedelta,这个是模块下的函数
# 或者from datetime import datetime,timedelta
import datetime
from flask import current_app, jsonify
from flask import g
from flask import redirect
from flask import render_template
from flask import request
from flask import session
from flask import url_for

from info import constants, db
from info.models import User, News, Category
from info.utils.commons import user_login_data
from info.utils.image_storage import image_storage
from info.utils.response_code import RET
from . import admin_blue


# 功能描述：新闻分类编辑
# 请求方式：GET,POST
#请求路径：/admin/news_type
# 请求参数,GET,无，POST,category_id,category_name
# 返回值：news_type.html,POST,jsonify
@admin_blue.route('/add_category', methods=['GET', 'POST'])
def admin_news_type():

    # 判断请求方式
    if request.method == 'GET':
        #　查询数据分类
        try:
            categories = Category.query.all()
        except Exception as e:
            current_app.logger.error(e)
            return jsonify(errno=RET.DBERR,errmsg='获取新闻分类失败')

        category_list = []
        for category in categories:
            category_list.append(category.to_dict())

        data = {
            'category_list':category_list
        }

        return render_template('admin/news_type.html',data=data)

    category_id = request.json.get('id')
    category_name = request.json.get('name')

    if not category_name: return jsonify(errno=RET.NODATA,errmsg='参数不全')

    # 根据是否有id判断是增加还是修改
    if category_id:
        try:
            category = Category.query.get(category_id)
            if not category:
                return jsonify(errno=RET.NODATA,errmsg='该新闻分类不存在')
            category.name = category_name
        except Exception as e:
            current_app.logger.error(e)
            return jsonify(errno=RET.DBERR,errmsg='修改失败')

    else:
        try:
            category = Category()
            category.name = category_name
            db.session.add(category)
            db.session.commit()
        except Exception as e:
            current_app.logger.error(e)
            db.session.rollback()
            return jsonify(errno=RET.DBERR,errmsg='增加失败')

    return jsonify(errno=RET.OK, errmsg='操作成功')


# 新闻详情编辑
# 访问路径：/admin/news_edit
# 访问方式：GET,POST
# 请求参数：get,new_id,category;post,news该有的都要有
# 返回值：jsonify

@admin_blue.route('/news_edit_detail', methods=['GET', 'POST'])
def admin_news_edit_detail():

    # 判断请求方式
    if request.method == 'GET':

        news_id = request.args.get('news_id')

        if not news_id: return jsonify(errno=RET.DATAERR,errmsg='参数不全')

        # 根据id获取新闻对象
        try:
            news = News.query.get(news_id)
            categories = Category.query.all()
        except Exception as e:
            current_app.logger.error(e)
            return jsonify(errno=RET.DBERR,errmsg='获取新闻失败')

        if not news: return jsonify(errno=RET.NODATA,errmsg='该新闻不存在')

        category_list = []
        for category in categories:
            category_list.append(category.to_dict())

        data = {
            'news_info':news.to_dict(),
            'category_list': category_list
        }

        return render_template('admin/news_edit_detail.html',data=data)

    # 获取参数
    news_id = request.form.get('news_id')
    title = request.form.get('title')
    digest = request.form.get('digest')
    category_id = request.form.get('category_id')
    # 获取的是图二进制留对象
    image = request.files.get('image')
    content = request.form.get('content')

    if not all([news_id,title,digest,category_id,image,content]):
        return jsonify(errno=RET.PARAMERR,errmsg='参数不全')

    # 获取新闻
    try:
        news = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg='获取新闻失败')

    if not news: return jsonify(errno=RET.NODATA,errmsg='该新闻不存在')

    # 上传图片
    try:
        image_name = image_storage(image.read())
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.THIRDERR,errmsg='七牛云异常')

    if not image_name: return jsonify(errno=RET.NODATA,errmsg='图片上传失败')

    try:
        news.title = title
        news.digest = digest
        news.category_id = category_id
        news.index_image_url = constants.QINIU_DOMIN_PREFIX+image_name
        news.content = content
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DATAERR,errmsg='编辑失败')

    return jsonify(errno=RET.OK,errmsg='编辑成功')



# 功能分析：新闻编辑
# 访问路径：/admin/news_edit
# 访问方式：GET
# 请求参数：GET,p,keyword
# 返回值：jsonify
@admin_blue.route('/news_edit')
def admin_news_edit():

    # 获取参数
    page = request.args.get('page','1')
    keyword = request.args.get('keyword')

    #数据类型转换
    try:
        page = int(page)
    except Exception as e:
        page = 1

    # 获取新闻列表
    try:
        if keyword:
            paginate = News.query.filter(News.status != 0,News.title.contains(keyword)).order_by(News.create_time.desc()).paginate(page, 10, False)
        else:
            paginate = News.query.filter(News.status != 0).order_by(News.create_time.desc()).paginate(page,10,False)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg='获取新闻失败')

    currentPage = paginate.page
    totalPage = paginate.pages
    items = paginate.items

    # 将新闻列表对象转化成字典对象
    news_list = []
    for item in items:
        news_list.append(item.to_dict())

    data = {
        'currentPage':currentPage,
        'totalPage':totalPage,
        'news_list':news_list
    }

    return render_template('admin/news_edit.html',data=data)


# 功能描述：新闻审核编辑
# 请求路径：/admin/news_review_detail
# 请求方式：get,post
# 请求参数：new_id
# 返回值：news_review_detail.html,data
@admin_blue.route('/news_review_detail', methods=['GET', 'POST'])
def admin_news_review_detail():

    # 请求方式
    if request.method == 'GET':
        # 写－１就不用判断，news_id不存在了，不存就就赋值－１
        news_id = request.args.get('news_id',-1)

        try:
            news = News.query.get(news_id)
        except Exception as e:
            current_app.logger.error(e)
            return jsonify(errno=RET.DATAERR,errmsg='新闻查询失败')

        # 判断该新闻是否存在
        if not news: return jsonify(errno=RET.DATAERR,errmsg='该新闻不存在')

        return render_template('admin/news_review_detail.html',news_info = news.to_dict())

    action = request.json.get('action')
    news_id = request.json.get('news_id')
    reason = request.json.get('reason')

    # 不为空判断
    if not all([action,news_id]):
        return jsonify(errno=RET.NODATA,errmsg='参数不全')

    # 判断操作类型
    if not action in ['accept','reject']:
        return jsonify(errno=RET.DATAERR,errmsg='操作类型有误')

    # 取出新闻对象
    try:
        news = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg='获取新闻失败')

    if not news: return jsonify(errno=RET.NODATA,errmsg='该新闻不存在')

    # 根据操作类型,更改新闻状态
    try:
        if action == 'accept':
            news.status = 0
        else:
            news.status = -1
            news.reason = reason
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg='更改失败')

    return jsonify(errno=RET.OK,errmsg='操作成功')


# 功能描述：新闻审核
# 访问路径：/admin/news_review
# 请求方式，GET
# 请求参数：GET,p,kword
# 返回值：
@admin_blue.route('/news_review')
def admin_news_review():

    page = request.args.get('page','1')
    keyword = request.args.get('keyword')
    # 数据类型转换
    try:
        page = int(page)
    except Exception as e:
        page = 1

    #查询数据库新闻列表
    try:
        # 方式１，条件容器
        filters = [News.status != 0]
        if keyword:
            filters.append(News.title.contains(keyword))
        paginate = News.query.filter(*filters).order_by(News.create_time.desc()).paginate(page, 10, False)

        # 方式２
        # if keyword:
        #     paginate = News.query.filter(News.status != 0, News.title.contains(keyword)).order_by(News.create_time.desc()).paginate(page, 10, False)
        # else:
        #     paginate = News.query.filter(News.status != 0).order_by(News.create_time.desc()).paginate(page,10,False)
    except Exception as e:
        current_app.logger.error(e)
        return render_template('admin/news_review.html',errmsg='新闻列表查询失败')

    current_page = paginate.page
    total_page = paginate.pages
    items = paginate.items

    # 将新闻列表对象转化成字典列表
    news_list = []
    for item in items:
        news_list.append(item.to_review_dict())

    data = {
        'current_page':current_page,
        'total_page':total_page,
        'news_list':news_list
    }

    return render_template('admin/news_review.html',data=data)



# 功能分析：统计用户数据列表
# 请求方式：GET
# 请求路径：/admin/user_list
# 请求参数：无
# 返回值：user_list.html,data字典
@admin_blue.route('/user_list')
def admin_user_list():

    page = request.args.get('page','1')

    # 参数类型转换
    try:
        page = int(page)
    except Exception as e:
        page = 1

    # 分页查询数据库
    try:
        paginate = User.query.filter(User.is_admin == False).order_by(User.create_time.asc()).paginate(page,10,False)
    except Exception as e:
        current_app.logger.error(e)
        return render_template('admin/user_list.html',errmsg='获取用户失败')

    current_page = paginate.page
    total_page = paginate.pages
    items = paginate.items

    user_list = []
    for item in items:
        user_list.append(item.to_admin_dict())

    data = {
        'current_page': current_page,
        'total_page':total_page,
        'user_list':user_list
    }

    return render_template('admin/user_list.html',data=data)


# 功能分析：用户统计
# 请求路径：/admin/user_count
#　请求方式：GET
# 请求参数：无
# 返回值：user_count的html页面,data字典
@admin_blue.route('/user_count')
def admin_user_count():

    # 查询用户总人数
    try:
        total_count = User.query.filter(User.is_admin == False).count()
    except Exception as e:
        current_app.logger.error(e)
        # 因为是表单提交，所以返回的不是jsonify数据，而是html页面
        return render_template('admin/user_count.html',errmsg='总用户数查询失败')

    # 月活查询, 获取时间..time.struct_time(tm_year=2018, tm_mon=11, tm_mday=12, tm_hour=18, tm_min=5, tm_sec=6, tm_wday=0, tm_yday=316, tm_isdst=0)
    cal = time.localtime()
    try:
        # 本月的１号０点,默认０分０秒
        start_mon_str = '%d-%d-01'%(cal.tm_year,cal.tm_mon) # 2018-11-12
        # 将时间字符串转化成时间对象,这里导包只能到import datetime
        start_mon_date = datetime.datetime.strptime(start_mon_str,'%Y-%m-%d')
        # 查询这个时间段内的用户数量
        mon_count = User.query.filter(User.last_login >= start_mon_date,User.is_admin == False).count()
    except Exception as e:
        current_app.logger.error(e)
        return render_template('admin/user_count.html',errmsg='月活数量查询失败')

    # 日活查询
    try:
        # 本月０点
        start_day_str = '%d-%d-%d'%(cal.tm_year,cal.tm_mon,cal.tm_mday)
        # 将时间字符串转化成字典
        start_day_date = datetime.datetime.strptime(start_day_str,'%Y-%m-%d')
        # 查询数据库
        day_count = User.query.filter(User.last_login >= start_day_date,User.is_admin == False).count()
    except Exception as e:
        current_app.logger.error(e)
        return render_template('admin/user_count.html',errmsg='日活数量查询失败')

    # 查询对应时间端内，对应的活跃人数
    active_date = []  # 活跃日期容器
    active_count = [] # 活跃数量容器
    # 方式一
    # try:
    #     for i in range(0,31):
    #         # 当前时间减去i天
    #         begin_time = start_day_date - datetime.timedelta(days=i)
    #         # 当前时间减去延后i天减１天
    #         end_time = start_day_date - datetime.timedelta(days=i-1)
    #         # 添加当前之间字符串到日期列表,begin_tiem.strftime('%m-%d')
    #         active_date.append(begin_time.strftime('%m-%d'))
    #         # 查询这一天注册的人数
    #         every_day_count = User.query.filter(User.is_admin == False,User.last_login >= begin_time,User.last_login <= end_time).count()
    #         # 添加到日活列表中
    #         active_count.append(every_day_count)
    # except Exception as e:
    #     current_app.logger.error(e)
    #     return render_template('admin/user_count.html',errmsg='查询日活列表失败')
    #

    # 方式二
    try:
        for i in range(0,31):
            # 当前时间减去i天
            now_time = start_day_date - datetime.timedelta(days=i)
            # 当前时间减去i+1 天
            before_time = start_day_date - datetime.timedelta(days=i+1)
            # 添加当前之间字符串到日期列表,now_tiem.strftime('%m-%d')
            active_date.append(now_time.strftime('%m-%d'))
            # 查询这一天注册的人数
            every_day_count = User.query.filter(User.is_admin == False,User.last_login >= before_time,User.last_login <= now_time).count()
            # 添加到日活列表中
            active_count.append(every_day_count)
    except Exception as e:
        current_app.logger.error(e)
        return render_template('admin/user_count.html',errmsg='查询日活列表失败')

    # # 列表反转
    active_date.reverse()
    active_count.reverse()

    # 拼接数据，渲染页面
    data = {
        'total_count':total_count,
        'mon_count':mon_count,
        'day_count':day_count,
        'active_date':active_date,
        'active_count':active_count
    }

    return render_template('admin/user_count.html',data=data)


# 功能描述：退出功能
# 请求方式：GET
# 请求路径：/admin/logout
# 请求参数：无
# 返回值：login.html
@admin_blue.route('/logout')
def admin_logout():

    session.pop('user_id')
    session.pop('nick_name')
    session.pop('mobile')
    session.pop('is_admin')

    return redirect(url_for('admin.admin_login'))

# 功能描述：管理员首页
# 请求参数：无
# 请求方式：GET
# 请求路径：/admin/index
# 返回值：渲染页面,user字典数据
@admin_blue.route('/index')
@user_login_data
def admin_index():

    data = {
        'admin_info':g.user.to_dict() if g.user else ''
    }

    return render_template('admin/index.html',data=data)

# 功能分析：管理员登陆页面
# 请求方式：GET,POST
#　请求路径：/admin/login
# 请求参数.GET，无，POST,username,password
# 返回值：login.html,　管理员首页
@admin_blue.route('/login', methods=['GET', 'POST'])
def admin_login():

    # 判断请求方式
    if request.method == 'GET':
        # 如果管理员等路过，之后在访问此页面的时候直接返回到管理员首页首页
        if session.get('is_admin') == True:
            return redirect(url_for('admin.admin_index'))
        return render_template('admin/login.html')

    # 获取请求参数
    username = request.form.get('username')
    password = request.form.get('password')

    # 不为空校验
    if not all([username,password]):
        return render_template('admin/login.html',errmsg='用户名和密码不能为空')

    # 根据用户名取出管理员对象
    try:
        admin = User.query.filter(User.mobile == username,User.is_admin==True).first()
    except Exception as e:
        current_app.logger.error(e)
        return render_template('admin/login.html',errmsg='管理员获取失败')

    # 判断管理员是否存在
    if not admin: return render_template('admin/login.html',errmsg='该管理员不存在')

    # 判断密码是否正确
    if not admin.check_password(password):
        return render_template('admin/login.html',errmsg='密码不正确')

    # 记录管理员登陆信息
    session['user_id'] = admin.id
    session['nick_name'] = admin.nick_name
    session['mobile'] = admin.mobile
    session['is_admin'] = True
    # 重定向url_for前面那个admin是蓝图的名字
    return redirect(url_for('admin.admin_index'))


